/**
 * @file device_grayscale.h
 * @author canrad (1517807724@qq.com)
 * @brief 灰度模块驱动
 *    一般的使用方法是，利用初始化器初始化一个灰度模块，然后调用灰度模块的读取函数grascale_get_data，
 *    然后根据state判断该路是否检测到线。不过要注意，下一次读取前需要调用grayscale_clear_state清空状态。
 *  使用方法：
 *      grascale_t g_grayscale = DEVICE_GRASCALE_INITIALIZER(
 *          DEVICE_SINGLE_GRASCALE_INITIALIZER(GPIOA, GPIO_PIN_0, VALID_ON_HIGH_LEVEL),
 *          DEVICE_SINGLE_GRASCALE_INITIALIZER(GPIOA, GPIO_PIN_1, VALID_ON_HIGH_LEVEL),
 *          DEVICE_SINGLE_GRASCALE_INITIALIZER(GPIOA, GPIO_PIN_2, VALID_ON_HIGH_LEVEL),
 *          DEVICE_SINGLE_GRASCALE_INITIALIZER(GPIOA, GPIO_PIN_3, VALID_ON_HIGH_LEVEL),
 *          DEVICE_SINGLE_GRASCALE_INITIALIZER(GPIOA, GPIO_PIN_4, VALID_ON_HIGH_LEVEL),
 *          DEVICE_SINGLE_GRASCALE_INITIALIZER(GPIOA, GPIO_PIN_5, VALID_ON_HIGH_LEVEL),
 *          DEVICE_SINGLE_GRASCALE_INITIALIZER(GPIOA, GPIO_PIN_6, VALID_ON_HIGH_LEVEL),
 *          DEVICE_SINGLE_GRASCALE_INITIALIZER(GPIOA, GPIO_PIN_7, VALID_ON_HIGH_LEVEL)
 *      );
 *      // 获取灰度数据
 *      grascale_get_data(&g_grayscale);
 *      // 清空状态
 *      grayscale_clear_state(&g_grayscale);
 * @version 0.1
 * @date 2024-08-16
 *
 * @copyright Copyright (c) 2024
 *
 */
#ifndef MYLIB_DEVICE_GRAYSCALE_H
#define MYLIB_DEVICE_GRAYSCALE_H

#include <mylib/mylib_config.h>

// 灰度的路数
#define GRAYSCALE_SIZE 8

typedef struct
{
    struct
    {
        GPIO_TypeDef* port;
        uint32_t      pin;
        int8_t        valid;   // 标明该路灰度何时有效
        bool          state;   // 灰度状态，如果为true，表示该路灰度检测到了
    } single_grayscales[GRAYSCALE_SIZE];
} grascale_t;

// 单路灰度的设备对象初始化器
#define DEVICE_SINGLE_GRASCALE_INITIALIZER(_port, _pin, _valid) \
    {                                                           \
        .port  = _port,                                         \
        .pin   = _pin,                                          \
        .valid = _valid,                                        \
    }

// 灰度的设备对象初始化器
#define DEVICE_GRASCALE_INITIALIZER(...)     \
    {                                        \
        .single_grayscales = { __VA_ARGS__ } \
    }

// 直接并口读取数据
void grascale_get_data(grascale_t* grascale);
// 清空状态
void grayscale_clear_state(grascale_t* grascale);

#endif   // !MYLIB_DEVICE_GRAYSCALE_H
